
// ================================================================================================
// -*- C++ -*-
// File: AntCommander.cpp
// Author: Guilherme R. Lampert
// Created on: 16/09/13
// Brief: Ant Commander AI bot for the "'Ants' Google AI challenge".
// ================================================================================================

#include "WorldState.hpp"

// AntCommander is the name of our application.
class AntCommander {

public:

	AntCommander() :
		worldState(NULL)
	{
		memset(&startupParams, 0, sizeof(StartupParameters));
	}

	void Start()
	{
		LOG("Ant Commander starting up...");

		// Collect startup parameters from STDIN:
		int turn = -1;
		std::string inputType, junk;

		// Finds out which turn it is:
		while (std::cin >> inputType)
		{
			if (inputType == "end")
			{
				LOG("WARNING: Game ended before starting!!!");
				return;
			}
			else if (inputType == "turn")
			{
				std::cin >> turn;
				break;
			}
			else
			{
				std::getline(std::cin, junk);
				LOG("Got junk line: \"" << junk.c_str() << "\"");
			}
		}

		if (turn < 0)
		{
			LOG("ERROR: Could not get the initial turn number! (Should be 0 ...)");
			return;
		}

		// Read game parameters:
		while (std::cin >> inputType)
		{
			if (inputType == "loadtime")
			{
				std::cin >> startupParams.loadTime;
			}
			else if (inputType == "turntime")
			{
				std::cin >> startupParams.turnTime;
			}
			else if (inputType == "rows")
			{
				std::cin >> startupParams.mapRows;
			}
			else if (inputType == "cols")
			{
				std::cin >> startupParams.mapCols;
			}
			else if (inputType == "turns")
			{
				std::cin >> startupParams.numTurns;
			}
			else if (inputType == "player_seed")
			{
				std::cin >> startupParams.playerSeed;
			}
			else if (inputType == "viewradius2")
			{
				std::cin >> startupParams.viewRadiusSquared;
				startupParams.viewRadius = sqrt(startupParams.viewRadiusSquared);
			}
			else if (inputType == "attackradius2")
			{
				std::cin >> startupParams.attackRadiusSquared;
				startupParams.attackRadius = sqrt(startupParams.attackRadiusSquared);
			}
			else if (inputType == "spawnradius2")
			{
				std::cin >> startupParams.spawnRadiusSquared;
				startupParams.spawnRadius = sqrt(startupParams.spawnRadiusSquared);
			}
			else if (inputType == "ready")
			{
				// End of parameter input
				break;
			}
			else
			{
				std::getline(std::cin, junk);
				LOG("Got junk line: \"" << junk.c_str() << "\"");
			}
		}

		// Create world state manager with startup parameters:
		worldState = new WorldState(&startupParams);
	}

	void PlayGame()
	{
		if (!worldState)
		{
			// Some error occurred inside Start(),
			// do nothing.
			return;
		}

		LOG("Entering game loop...");

		while (std::cin >> (*worldState))
		{
			worldState->Update();
		}
	}

	~AntCommander()
	{
		LOG("Ant Commander shutting down...");

		delete worldState;
		worldState = NULL;
	}

private:

	StartupParameters startupParams;
	WorldState * worldState;
};

// Application entry point:
int main(int argc, char * argv[])
{
	// Unused arguments:
	(void)argc;
	(void)argv;

	// Allow our output to be independent from STDOUT:
	std::cout.sync_with_stdio(false);

	AntCommander antCommander;
	antCommander.Start();
	antCommander.PlayGame();

	return (0);
}
